package com.easylinkin.linkappapi.powerdistribution.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.powerdistribution.entity.DistributionCabinet;
import com.easylinkin.linkappapi.powerdistribution.entity.DistributionRoom;
import com.easylinkin.linkappapi.powerdistribution.entity.DistributionRoomRefDevice;
import com.easylinkin.linkappapi.powerdistribution.mapper.DistributionRoomMapper;
import com.easylinkin.linkappapi.powerdistribution.service.DistributionCabinetService;
import com.easylinkin.linkappapi.powerdistribution.service.DistributionRoomRefDeviceService;
import com.easylinkin.linkappapi.powerdistribution.service.DistributionRoomService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * <p>
 * 配电房 服务实现类
 * </p>
 *
 * @author TongJie
 * @since 2020-08-05
 */
@Service
public class DistributionRoomServiceImpl extends ServiceImpl<DistributionRoomMapper, DistributionRoom> implements DistributionRoomService {


    private static final Logger LOGGER = LoggerFactory.getLogger(DistributionRoomServiceImpl.class);

    @Resource
    private CommonService commonService;
    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    @Resource
    private DistributionCabinetService distributionCabinetService;
    @Resource
    private DistributionRoomRefDeviceService distributionRoomRefDeviceService;

    @Override
    public void add(DistributionRoom distributionRoom) {
        validParamRequired(distributionRoom);
        validParamFormat(distributionRoom);
        validRepeat(distributionRoom);
        commonService.setCreateAndModifyInfo(distributionRoom);
        LinkappUser user = linkappUserContextProducer.getCurrent();
        distributionRoom.setTenantId(user.getTenantId());
        save(distributionRoom);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDetailConfig(DistributionRoom distributionRoom) {
//        更新关联的配电柜信息
        setDetailConfigDistributionCabinet(distributionRoom);

        QueryWrapper qw = new QueryWrapper();
        qw.eq("distribution_room_id", distributionRoom.getId());
        //        删除旧的与设备管理
        distributionRoomRefDeviceService.remove(qw);
        //        新增设备与配电房关联
        List<Device> devices = distributionRoom.getDeviceList();
        if (ObjectUtils.isNotEmpty(devices)) {
            int sortNo = 0;
            for (Device device : devices) {
                DistributionRoomRefDevice distributionRoomRefDevice = new DistributionRoomRefDevice();
                distributionRoomRefDevice.setDeviceCode(device.getCode());
                distributionRoomRefDevice.setDistributionRoomId(distributionRoom.getId());
                distributionRoomRefDevice.setSortNo(sortNo++);
                distributionRoomRefDeviceService.add(distributionRoomRefDevice);
            }
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDetailConfigDistributionCabinet(DistributionRoom distributionRoom) {
        Assert.notNull(distributionRoom, "参数为空");
        Assert.hasLength(distributionRoom.getId(), "参数id 为空");

        QueryWrapper qw = new QueryWrapper();
        qw.eq("distribution_room_id", distributionRoom.getId());
//        移除旧的与配电柜柜关联

        List<DistributionCabinet> oldDistributionCabinetList = distributionCabinetService.list(qw);
        if (ObjectUtils.isNotEmpty(oldDistributionCabinetList)) {
            distributionCabinetService.deleteBatch(oldDistributionCabinetList);
        }

        List<DistributionCabinet> distributionCabinetList = distributionRoom.getDistributionCabinetList();
        if (ObjectUtils.isNotEmpty(distributionCabinetList)) {
            distributionCabinetList.forEach(distributionCabinet -> {
                distributionCabinet.setDistributionRoomId(distributionRoom.getId());
                distributionCabinetService.add(distributionCabinet);
            });
        }
    }


    /**
     * 校验重复
     */
    private void validRepeat(DistributionRoom distributionRoom) {
        QueryWrapper<DistributionRoom> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", distributionRoom.getName());
        queryWrapper.eq("tenant_id", linkappUserContextProducer.getNotNullCurrent().getTenantId());
        List<DistributionRoom> list = baseMapper.selectList(queryWrapper);
        if (list.size() == 0) {
            return;
        }
        if (list.size() > 1) {
            throw new BusinessException("配电房名称有重复");
        }
        if (StringUtils.isEmpty(distributionRoom.getId())) {
            throw new BusinessException("配电房名称已存在");
        }
        if (!distributionRoom.getId().equals(list.get(0).getId())) {
            throw new BusinessException("配电房名称已存在");
        }
        
    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(DistributionRoom distributionRoom) {
        Assert.notNull(distributionRoom, "参数为空");
        Assert.notNull(distributionRoom.getCompanyInfoId(), "所属公司为空");
        Assert.isTrue(StringUtils.isNotBlank(distributionRoom.getName()), "名称为空");
        Assert.hasLength(distributionRoom.getAreaId(), "参数区域为空");

    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(DistributionRoom distributionRoom) {
        Assert.isTrue(distributionRoom.getName() == null || distributionRoom.getName().length() <= 32, "名称超长");
        Assert.isTrue(distributionRoom.getDescription() == null || distributionRoom.getDescription().length() <= 255, "配电房描述超长");
        Assert.isTrue(distributionRoom.getTenantId() == null || distributionRoom.getTenantId().length() <= 32, "租户id超长");
        Assert.isTrue(distributionRoom.getAreaId() == null || distributionRoom.getAreaId().length() <= 32, "区域id超长");
    }

    @Override
    public List<DistributionRoom> getDistributionRooms(DistributionRoom distributionRoom) {
        distributionRoom.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        List<String> spacesIds = commonService.getCurrentUserSpaceIds();
        return baseMapper.getDistributionRooms(distributionRoom, spacesIds);
    }

    @Override
    public IPage<DistributionRoom> getDistributionRooms(Page page, DistributionRoom distributionRoom) {
        distributionRoom.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        List<String> spacesIds = commonService.getCurrentUserSpaceIds();
        return baseMapper.getDistributionRooms(page, distributionRoom, spacesIds);
    }

    @Override
    public DistributionRoom getDistributionRoom(String id) {
        DistributionRoom record = baseMapper.getDistributionRoom(id);
        record.setDeviceList(getRefdevices(id));
        return record;
    }

    @Override
    public DistributionRoom getDistributionRoomMonitor(String id) {
        DistributionRoom distributionRoom = getById(id);

        DistributionCabinet distributionCabinet = new DistributionCabinet();
        distributionCabinet.setDistributionRoomId(id);
        List<DistributionCabinet> distributionCabinets = distributionCabinetService.getRealTimeDistributionCabinetWithStatus(distributionCabinet);
        distributionRoom.setDistributionCabinetList(distributionCabinets);
        return distributionRoom;
    }

    @Override
    public void updateDistributionRoom(DistributionRoom distributionRoom) {
        Assert.notNull(distributionRoom, "参数为空");
        DistributionRoom originDistributionRoom = getById(distributionRoom.getId());
        Assert.notNull(originDistributionRoom, "原配电房不存在");
        validRepeat(distributionRoom);
        validParamFormat(distributionRoom);
        commonService.setModifyInfo(distributionRoom);
        updateById(distributionRoom);

    }

    @Override
    public void deleteBatch(List<DistributionRoom> distributionRoomList) {
        Assert.notEmpty(distributionRoomList, "参数为空");
        List<String> ids = distributionRoomList.stream().map(DistributionRoom::getId).collect(Collectors.toList());
        QueryWrapper qw = new QueryWrapper();
        qw.in("distribution_room_id", ids);
        Assert.isTrue(distributionCabinetService.count(qw) == 0, "被配电柜引用，不允许删除");
        Assert.isTrue(distributionRoomRefDeviceService.count(qw) == 0, "与设备绑定，不允许删除");
        removeByIds(ids);
    }

    @Override
    public List<Device> getRefdevices(String id) {
        return baseMapper.getRefdevices(id);
    }
}
